package com.ays.service;

import cn.hutool.json.JSONObject;
import cn.hutool.json.XML;
import com.ays.bean.*;
import com.ays.bean.xml.Model;
import com.ays.bean.xml.Procedure;
import com.ays.bean.xml.StatusParameter;
import com.ays.comm.XMLHandle;
import com.ays.mapper.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Administrator
 * @date 2024/6/5
 * @desc 接收推送信息处理、日志手动重试
 */
@Service
@Slf4j
public class HisRequestHandleService {

    @Autowired
    private HisBusinessService hisBusinessService;
    @Autowired
    private SyncLogService syncLogService;

    @Autowired
    private AtmSyncLogMapper atmSyncLogMapper;

    @Autowired
    private AtmOperationScheduleMapper atmOperationScheduleMapper;

    @Autowired
    private AtmHisUsersMapper atmHisUsersMapper;

    @Autowired
    private AtmDeptDictMapper atmDeptDictMapper;

    @Autowired
    private AtmOperationMasterMapper atmOperationMasterMapper;

    // 根据http请求体处理
    public String handle(String module, HttpServletRequest request) throws IOException {
        JSONObject entries = XMLHandle.getJson(request,module);
        String business = hisBusinessService.business(entries,module);
        syncLogService.insertLog(module,"",entries.toJSONString(0),"0",business);
        return XMLHandle.getXml(business);
    }

    // 根据xml字符串处理
    public String handle(String module,String xml){
        try {
            JSONObject entries = XMLHandle.getJson(xml,module);
            String result = hisBusinessService.business(entries, module);
            syncLogService.insertLog(module,xml,entries.toJSONString(0),"ok".equals(result)?"0":"-1",result);
            return result;
        }catch(Exception e){
            e.printStackTrace();
            syncLogService.insertLog(module,xml,"","-1",e.getMessage());
            return e.getMessage();
        }
    }

    // 根据推送日志重试
    public String logRetry(Set<String> logIds,String flag){
        ArrayList<String> success = new ArrayList<String>();
        if("0".equals(flag)){
            List<AtmSyncLog> atmSyncLogs = atmSyncLogMapper.selectList(null);
            logIds = atmSyncLogs.stream().map(AtmSyncLog::getLogId).collect(Collectors.toSet());
        }
        for(String logId :logIds){
            AtmSyncLog atmSyncLog = atmSyncLogMapper.queryById(logId);
            if(ObjectUtils.isEmpty(atmSyncLog))
                continue;
            System.out.println(logId);
            JSONObject entries = XML.toJSONObject(atmSyncLog.getContent());
            JSONObject body = entries.get("Request", JSONObject.class).get("Body", JSONObject.class);
            String business = hisBusinessService.business(body,atmSyncLog.getModule());
            success.add(logId);
        }
        System.out.println(success);
        return "ok";
    }

    // 手术回写
    public String writeBack(Map<String,String> param){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        AtmOperationSchedule sp = new AtmOperationSchedule();
        sp.setScheduleId(param.get("scheduleId"));
        sp.setPatientId(param.get("patientId"));
        sp.setVisitId(param.get("visitId"));
        List<AtmOperationSchedule> atmOperationSchedules = atmOperationScheduleMapper.selectList(sp);
        StatusParameter parameter = new StatusParameter();
        if(!ObjectUtils.isEmpty(atmOperationSchedules)){
            AtmOperationSchedule schedule = atmOperationSchedules.get(0);
            AtmHisUsers pu = new AtmHisUsers();
            pu.setUserId(schedule.getEnteredBy());
            List<AtmHisUsers> users = atmHisUsersMapper.selectList(pu);
            AtmDeptDict pd = new AtmDeptDict();
            pd.setDeptCode(schedule.getDeptStayed());
            List<AtmDeptDict> deptDicts = atmDeptDictMapper.selectList(pd);
            parameter.setPATPatientID(schedule.getPatientId());
            parameter.setPAADMVisitNumber(schedule.getVisitId());
            parameter.setRISRSystemType("AN");
            parameter.setOperAppID(schedule.getScheduleId());
            parameter.setStatusCode(param.get("status"));
            if(!ObjectUtils.isEmpty(users)){
                AtmHisUsers user = users.get(0);
                parameter.setUpdateUserCode(user.getUserId());
                parameter.setUpdateUserName(user.getUserName());
                parameter.setUpdateDateTime(sdf.format(new Date()));
            }
            if(!ObjectUtils.isEmpty(deptDicts)){
                AtmDeptDict dict = deptDicts.get(0);
                parameter.setESOperateDeptCode(dict.getDeptCode());
                parameter.setESOperateDept(dict.getDeptName());
            }
        }
        String xml = XML.toXml(new JSONObject(parameter));
        return xml;
    }

    // 排班回写
    public String arrangeBack(Map<String,String> param){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = sdf.format(new Date());
        Model model = new Model();
        Procedure procedure = new Procedure();

        AtmOperationMaster mp = new AtmOperationMaster();
        mp.setOperId(param.get("scheduleId"));
        mp.setPatientId(param.get("patientId"));
        mp.setVisitId(param.get("visitId"));
        List<AtmOperationMaster> atmOperationMasters = atmOperationMasterMapper.selectList(mp);
        AtmOperationMaster atmOperationMaster = atmOperationMasters.get(0);
        model.setApplicationID(atmOperationMaster.getOperId())
                .setStatusCode("Arrange")
                .setStatusDesc("手术排班提交")
                .setSubmitUserID(atmOperationMaster.getEnteredBy())
                .setSubmitUser(atmOperationMaster.getSurgeon())
                .setSubmitDateTime(time)
                .setOperRoomID(atmOperationMaster.getOperatingRoom())
                .setOperRoom(atmOperationMaster.getOperatingRoom())
                .setOperSeq(String.valueOf(atmOperationMaster.getSequence()));
        procedure.setApplicationID(atmOperationMaster.getOperId())
                .setCode("OPA")
                .setDescription("手术排班提交")
                .setDate(time.split(" ")[0])
                .setTime(time.split(" ")[1])
                .setUserID(atmOperationMaster.getEnteredBy())
                .setUser(atmOperationMaster.getSurgeon())
                .setAction("手术排班提交");
        String p = XML.toXml(new JSONObject(procedure));
        String m = XML.toXml(new JSONObject(procedure));
        String xml = p + "<Procedures><Procedure>"+m+"</Procedure></Procedures>";
        return xml;
    }

    // 手术登记回写
    public String registrationBack(Map<String,String> param){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat d = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat t = new SimpleDateFormat("HH:mm:ss");

        AtmOperationMaster mp = new AtmOperationMaster();
        mp.setOperId(param.get("scheduleId"));
        mp.setPatientId(param.get("patientId"));
        mp.setVisitId(param.get("visitId"));

        List<AtmOperationMaster> atmOperationMasters = atmOperationMasterMapper.selectList(mp);
        AtmOperationMaster ms = atmOperationMasters.get(0);
        String model = "<ApplicationID>%s</ApplicationID><StatusCode>Finish</StatusCode><StatusDesc>完成</StatusDesc><OperPositionID></OperPositionID><OperPosition>%s</OperPosition><AnaMethodID>%s</AnaMethodID><AnaMethod>%s</AnaMethod><PostDiagnosisID/><PostDiagnosis/><OperRoomID>%s</OperRoomID><OperRoom>%s</OperRoom><OperSeq>%s</OperSeq><SubmitDate/><SubmitUserID/><SubmitUser/>";
        model = String.format(model, ms.getOperId(),ms.getOperationPosition(),ms.getAnesthesiaMethod(),
                ms.getAnesthesiaMethod(),ms.getOperatingRoom(),ms.getOperatingRoom(),ms.getSequence());

        String step ="<AreaIn><Code>AreaIn</Code><Description>入手术室</Description><Date>%s</Date><Time>%s</Time><Note/></AreaIn><AnaStart><Code>AnaStart</Code><Description>麻醉开始</Description><Date>%s</Date><Time>%s</Time><Note/></AnaStart><OperStart><Code>OperStart</Code><Description>手术开始</Description><Date>%s</Date><Time>%s</Time><Note/></OperStart><OperEnd><Code>OperEnd</Code><Description>手术结束</Description><Date>%s</Date><Time>%s</Time><Note/></OperEnd><AnaEnd><Code>AnaEnd</Code><Description>麻醉结束</Description><Date>%s</Date><Time>%s</Time><Note/></AnaEnd><AreaOut><Code>AreaOut</Code><Description>出手术室</Description><Date>%s</Date><Time>%s</Time><Note/></AreaOut>";
        step = String.format(step,d.format(ms.getInDateTime()),t.format(ms.getInDateTime()),d.format(ms.getAnesStartTime()),t.format(ms.getAnesStartTime())
                    ,d.format(ms.getStartDateTime()),t.format(ms.getStartDateTime()),d.format(ms.getEndDateTime()),t.format(ms.getEndDateTime())
                    ,d.format(ms.getAnesEndTime()),t.format(ms.getAnesEndTime()),d.format(ms.getOutDateTime()),t.format(ms.getOutDateTime()));

        String procedures="<Procedures><Procedure><Code>CISANAI</Code><Description>入手术室</Description><Date>%s</Date><Time>%s</Time><UserID>%s</UserID><User>%s</User><Note/><Seq/></Procedure><Procedure><Code>CISANANS</Code><Description>麻醉开始</Description><Date>%s</Date><Time>%s</Time><UserID>%s</UserID><User>%s</User><Note/><Seq/></Procedure><Procedure><Code>CISANOPS</Code><Description>手术开始</Description><Date>%s</Date><Time>%s</Time><UserID>%s</UserID><User>%s</User><Note/><Seq/></Procedure><Procedure><Code>CISANOPF</Code><Description>手术结束</Description><Date>%s</Date><Time>%s</Time><UserID>%s</UserID><User>%s</User><Note/><Seq/></Procedure><Procedure><Code>CISANANF</Code><Description>麻醉结束</Description><Date>%s</Date><Time>%s</Time><UserID>%s</UserID><User>%s</User><Note/><Seq/></Procedure><Procedure><Code>CISANAO</Code><Description>出手术室</Description><Date>%s</Date><Time>%s</Time><UserID>%s</UserID><User>%s</User><ActionCode/><Action/><Note/><Seq/></Procedure></Procedures>";
        procedures = String.format(procedures,d.format(ms.getInDateTime()),t.format(ms.getInDateTime()),d.format(ms.getAnesStartTime()),t.format(ms.getAnesStartTime())
                ,d.format(ms.getStartDateTime()),t.format(ms.getStartDateTime()),d.format(ms.getEndDateTime()),t.format(ms.getEndDateTime())
                ,d.format(ms.getAnesEndTime()),t.format(ms.getAnesEndTime()),d.format(ms.getOutDateTime()),t.format(ms.getOutDateTime()));

        String actualOperations = "<ActualOperations><Operation d5p1:type=\"Operation\"><OperNameID></OperNameID><OperName>%s</OperName><OperNameStandardCode/><OperCategoryID>%s</OperCategoryID><OperCategory>%s</OperCategory><BladeTypeID>%s</BladeTypeID><BladeType>%s</BladeType><BodySiteID>%s</BodySiteID><BodySite>%s</BodySite><SurgicalDepartmentID>%s</SurgicalDepartmentID><SurgicalDepartment>%s</SurgicalDepartment><Surgeon><CareProvider><RowId>%s</RowId><Name>%s</Name><DepartmentID/><Department/></CareProvider></Surgeon><Assistants><CareProvider><RowId>%s</RowId><Name>%s</Name><DepartmentID/><Department/></CareProvider><CareProvider><RowId>%s</RowId><Name>%s</Name><DepartmentID/><Department/></CareProvider></Assistants><ExternalExpert/><Note/></Operation></ActualOperations>";
        actualOperations = String.format(actualOperations,ms.getOperationName(),ms.getOperationScale(),
                ms.getOperationScale(),ms.getQiekouClass(),ms.getQiekouClass(),ms.getOperationPosition(),
                ms.getOperationPosition(),ms.getOperatingDept(),ms.getOperatingDept(),ms.getSurgeon(),
                ms.getSurgeon(),ms.getFirstAssistant(),ms.getFirstAssistant(),ms.getSecondAssistant(),
                ms.getSecondAssistant());

        String xml = model + step + procedures + actualOperations;
        xml = xml.replace("null", "");
        return xml;
    }
}
